package vue;

import controleur.Controleur;
import Properties.BundleTool;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Insets;
import java.io.File;
import java.util.Locale;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

/**
 * Classe representant l'interface 
 * graphique de l'application
 * @author D.Romain
 * @author O.Riad
 */
public final class Vue extends JFrame {

    //OBJETS DU MENU
    private JMenu menu, langue, mode, fichier;
    private JMenuItem quitter, francais, anglais, normal, debug, ouvrir, sauvegarder;
    //ACTION COMMANDES DU MENU
    public static final String MENU = "menu";
    public static final String QUITTER = "quitter";
    public static final String LANGUE = "langue";
    public static final String FRANCAIS = "francais";
    public static final String ANGLAIS = "anglais";
    public static final String MODE = "mode";
    public static final String FICHIER = "fichier";
    public static final String NORMAL = "normal";
    public static final String DEBUG = "debug";
    public static final String OUVRIR = "ouvrir";
    public static final String SAUVEGARDER = "sauvegarder";
    //BOUTONS
    private JButton lancer, pasapas;
    //ACTION COMMANDE DES BOUTONS
    public static final String LANCER = "lancer";
    public static final String PASAPAS = "pasapas";
    //JTextField
    public JTextArea source, console, nLigne, variables;
    //ACTION COMMANDE DES JTextField
    public static final String SOURCE = "source";
    public static final String CONSOLE = "console";
    //VARIABLE
    private int num;
    //EXTENSION D'UN FICHER PICOL
    private static final String EXTENSION_PICOL = ".picol";

    /**
     * Constructeur de la vue,
     * il initialise les différents panels
     * et paramètre la fenêtre principale
     */
    public Vue() {

        this.setSize(600, 600);
        this.setLocation(320, 40);
        this.setLayout(new BorderLayout());

        this.initiliseBarMenu();

        //this.add(this.panelRadioButton(), BorderLayout.SOUTH);
        this.add(this.panelBoutons(), BorderLayout.NORTH);
        this.add(new JScrollPane(this.panelTextArea()), BorderLayout.CENTER);
        this.add(this.panelTextArea2(), BorderLayout.SOUTH);


        this.nommerComposants();
        this.bloqueItemLangueCourante();

        this.setVisible(true);
    }

    /**
     * Initalisation de la barre de menu et
     * de ses coposants
     */
    private void initiliseBarMenu() {
        this.quitter = new JMenuItem();
        this.quitter.setActionCommand(QUITTER);
        this.langue = new JMenu();
        this.langue.setActionCommand(LANGUE);
        this.francais = new JMenuItem();
        this.francais.setActionCommand(FRANCAIS);
        this.anglais = new JMenuItem();
        this.anglais.setActionCommand(ANGLAIS);


        this.langue.add(this.francais);
        this.langue.add(this.anglais);

        this.menu = new JMenu();

        this.menu.add(this.langue);
        this.menu.add(quitter);

        this.ouvrir = new JMenuItem();
        this.ouvrir.setActionCommand(OUVRIR);
        this.sauvegarder = new JMenuItem();
        this.sauvegarder.setActionCommand(SAUVEGARDER);

        this.fichier = new JMenu();
        this.fichier.add(this.ouvrir);
        this.fichier.add(this.sauvegarder);

        this.normal = new JMenuItem();
        this.normal.setActionCommand(NORMAL);
        this.normal.setEnabled(false);
        this.debug = new JMenuItem();
        this.debug.setActionCommand(DEBUG);

        this.mode = new JMenu();
        this.mode.add(this.normal);
        this.mode.add(this.debug);

        JMenuBar menuBar = new JMenuBar();
        menuBar.add(menu);
        menuBar.add(fichier);
        menuBar.add(mode);
        this.setJMenuBar(menuBar);

    }

    /**
     * Initalisation des boutons
     */
    public JPanel panelBoutons() {
        JPanel panelBouton = new JPanel();
        this.lancer = new JButton();
        this.lancer.setIcon(new ImageIcon(this.getClass().getResource("/ressources/images/flech.png")));
        this.lancer.setBorder(null);
        this.lancer.setActionCommand(LANCER);
        this.pasapas = new JButton();
        this.pasapas.setIcon(new ImageIcon(this.getClass().getResource("/ressources/images/debug.png")));
        this.pasapas.setBorder(null);
        this.pasapas.setActionCommand(PASAPAS);

        panelBouton.add(this.lancer);
        panelBouton.add(this.pasapas);

        return panelBouton;
    }

    /**
     * Initalisation du panel contenant
     * le code source
     */
    public JPanel panelTextArea() {
        JPanel panelInput = new JPanel();
        panelInput.setLayout(new BorderLayout());

        Font ft = new Font("Verdana", 5, 14);
        this.nLigne = new JTextArea(22, 2);
        this.nLigne.setEditable(false);
        this.nLigne.setBorder(null);
        this.nLigne.setFont(ft);
        this.nLigne.setForeground(Color.orange);
        this.source = new JTextArea(22, 40);
        this.source.setFont(ft);
        this.source.setBorder(null);

        source.getDocument().addDocumentListener(new DocumentListener() {

            @Override
            public void insertUpdate(DocumentEvent de) {
                majLigne();
            }

            @Override
            public void removeUpdate(DocumentEvent de) {
                majLigne();
            }

            @Override
            public void changedUpdate(DocumentEvent de) {
                majLigne();
            }
        });
        panelInput.add(this.nLigne, BorderLayout.WEST);
        panelInput.add(this.source, BorderLayout.CENTER);


        return panelInput;
    }

    /**
     * Initalisation du panel contenant
     * la console (resultats)
     */
    public JPanel panelTextArea2() {
        JPanel panelInput = new JPanel();
        panelInput.setLayout(new BorderLayout());

        this.console = new JTextArea(5, 30);
        this.console.setEditable(false);
        this.console.setBackground(Color.DARK_GRAY);
        this.console.setForeground(Color.WHITE);
        this.console.setMargin(new Insets(0, 10, 0, 0));
        this.console.setBorder(null);

        this.variables = new JTextArea(5, 15);
        this.variables.setMargin(new Insets(0, 10, 0, 0));
        this.variables.setVisible(false);
        this.variables.setBorder(null);
        this.console.setEditable(false);


        panelInput.add(new JScrollPane(this.console), BorderLayout.CENTER);
        panelInput.add(new JScrollPane(this.variables), BorderLayout.EAST);
        return panelInput;
    }

    /**
     * Permet de nommer l'ensemble des coposants
     * et titre de l'application
     */
    public final void nommerComposants() {

        setTitle(BundleTool.getBundle().getString("titre"));
        this.quitter.setText(BundleTool.getBundle().getString("quitter"));
        this.menu.setText(BundleTool.getBundle().getString("menu"));
        this.langue.setText(BundleTool.getBundle().getString("langue"));
        this.francais.setText(BundleTool.getBundle().getString("fr_FR"));
        this.anglais.setText(BundleTool.getBundle().getString("en_GB"));
        this.fichier.setText(BundleTool.getBundle().getString("fichier"));
        this.ouvrir.setText(BundleTool.getBundle().getString("ouvrir"));
        this.mode.setText(BundleTool.getBundle().getString("mode"));
        this.normal.setText(BundleTool.getBundle().getString("normal"));
        this.debug.setText(BundleTool.getBundle().getString("debug"));
        this.sauvegarder.setText(BundleTool.getBundle().getString("save"));

    }

    /**
     * Abonne les éléments de la vue avec leur
     * listener
     * @param ctrl controleur de l'application
     */
    public void abonnement(Controleur ctrl) {

        //ABONNEMENT MENU_ITEM        
        this.francais.addActionListener(ctrl);
        this.anglais.addActionListener(ctrl);
        this.quitter.addActionListener(ctrl);
        this.ouvrir.addActionListener(ctrl);
        this.normal.addActionListener(ctrl);
        this.debug.addActionListener(ctrl);
        this.sauvegarder.addActionListener(ctrl);

        //ABONNEMENT BOUTONS
        this.lancer.addActionListener(ctrl);
        this.pasapas.addActionListener(ctrl);


        //Quitter (fenetre)
        this.addWindowListener(ctrl);
    }

    /**
     * Affiche une fenetre de dialogue avec
     * un message d'information destiné à l'utilisateur
     * @param titre titre de la fenetre de dialogue
     * @param message message à afficher
     */
    public void afficherMessageInfo(String titre, String message) {
        JOptionPane.showMessageDialog(this, message,
                titre,
                JOptionPane.INFORMATION_MESSAGE);
    }

    /**
     * Affiche une fenetre de dialogue avec
     * un message d'erreur destiné à l'utilisateur
     * @param titre titre de la fenetre de dialogue
     * @param message message à afficher
     */
    public void afficherMessageErreur(String titre, String message) {
        JOptionPane.showMessageDialog(this, message,
                titre,
                JOptionPane.WARNING_MESSAGE);
    }

    /**
     * Grise l'item de selection de la langue
     * déjà en place
     */
    public final void bloqueItemLangueCourante() {
        Locale localeCourante = BundleTool.getBundle().getLocale();
        if (localeCourante.equals(Locale.FRANCE)) {
            this.francais.setEnabled(false);
        } else {
            this.francais.setEnabled(true);
        }
        if (localeCourante.equals(Locale.UK)) {
            this.anglais.setEnabled(false);
        } else {
            this.anglais.setEnabled(true);
        }
    }

    /**
     * Permet de griser le menu "normal"
     * @param grise true si intention de griser
     */
    public void griserModeNormal(Boolean grise) {
        this.normal.setEnabled(grise);
    }

    /**
     * Permet de griser le menu "debug"
     * @param grise true si intention de griser
     */
    public void griserModeDebug(Boolean grise) {
        this.debug.setEnabled(grise);
    }

    /**
     * Vide l'ensemble des champs
     */
    public void effacerChamps() {
        this.source.setText("");
        this.console.setText("");
    }

    /**
     * Méthode permettant de mettre 
     * à jour le numéro de ligne
     * liée aux lignes du code source
     */
    public void majLigne() {
        nLigne.setText("");
        num = 1;
        while (nLigne.getLineCount() < source.getLineCount()) {
            if (num == 1) {
                nLigne.setText("" + num + ".");
                num++;
            } else {
                nLigne.setText(nLigne.getText() + "\n" + num + ".");
                num++;
            }
        }
    }

    /**
     * Méthode renvoyant un JFileChooser  
     * associé à filtre (.picol)
     * @return JFileChooser muni d'un filtre pour fichier picol
     */
    private JFileChooser recuprerFiltre() {
        JFileChooser f = new JFileChooser();

        /*----------- Gestion du filtrage ---------*/
        f.setAcceptAllFileFilterUsed(false);
        javax.swing.filechooser.FileFilter filter = new javax.swing.filechooser.FileFilter() {

            @Override
            public boolean accept(File file) {
                if (file.getName().toLowerCase().endsWith(EXTENSION_PICOL)) {
                    return true;
                }
                return false;
            }

            @Override
            public String getDescription() {
                return EXTENSION_PICOL;
            }
        };

        f.addChoosableFileFilter(filter);
        /*-------------------------------------------*/
        return f;
    }

    /**
     * Permet la selection d'un fichier (*.picol)
     * par le biais d'une boite de dialogue
     * @return path du fichier selectionné
     */
    public String selectionnerFichierPicol() {
        JFileChooser f = this.recuprerFiltre();
        String path = "";
        if (f.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
            path = f.getSelectedFile().getAbsolutePath();
        }
        return path;
    }

     /**
     * Permet la selection d'un chemin et 
     * l'ajout d'un nom de fichier (*.picol) 
     * par le biais d'une boite de dialogue
     * @return path du fichier que l'on veut créer
     */
    public String enregistrerSous() {

        String fichier = null;
        JFileChooser chooser = this.recuprerFiltre();
        // Dossier Courant
        chooser.setCurrentDirectory(new File("." + File.separator));
        //Affichage et récupération de la réponse de l'utilisateur
        int reponse = chooser.showDialog(chooser, BundleTool.getBundle().getString("saveas"));

        // Si l'utilisateur clique sur OK
        if (reponse == JFileChooser.APPROVE_OPTION) {
            // Récupération du chemin du fichier
            fichier = chooser.getSelectedFile().toString();
        }
        return fichier + EXTENSION_PICOL;
    }

    /**
     * Remplace le text source dans le JTextArea
     * concerne par le text reçu en paramètre
     * @param src code source
     */
    public void setSource(String src) {
        this.source.setText(src);
    }

    /**
     * Renvois la chaîne de caracètre
     * présente dans le JTextArea 
     * destiné au code source à
     * analyser
     * @return String du code source
     */
    public String getSource() {
        return this.source.getText();
    }
    
    /**
     * Remplace le text present dans la 
     * fenêtre affichant les varaibles
     * @param v Text à mettre dans le JtextArea destiné aux variables
     */
    public void setVariables(String v) {
        this.variables.setText(v);
    }

    /**
     * Remplace le texte de la console
     * @param result String du text remplacant 
     */
    public void setResultat(String result) {
        this.console.setText(result);
    }

    /**
     * Ajoute un String à la suite
     * dans la console 
     * @param result String à ajouter
     */
    public void addResultat(String result) {
        this.console.append(result);
    }

    /**
     * Grise la fenêtre affichant les variables
     */
    public void griserVariables() {
        this.variables.setEnabled(false);
    }

    /**
     * Degrise la fenêtre affichant les variables
     */
    public void degriserVariables() {
        this.variables.setEnabled(true);
    }
}
